package crivia.ecp.carry.html.table;

import java.util.ArrayList;
import java.util.List;

import crivia.ecp.carry.html.DO;
import crivia.ecp.exception.WrongDocumentObject;

public class TableRow extends DO {
	
	public TableRow(Table table){
		baseTable = table;
	}

	@Override
	protected String name() {
		return "tr";
	}
	@Override
	protected String innerHTML() {
		int tableCellSize = getBaseTable().cellSize();
		int rowCellSize = cellSize();
		int n = tableCellSize - rowCellSize;
		if (n < 0){
			throw Exception_CellsOver(
				"The Row Cell Size Is More Then Table Cell Size Of All Row."
					+"\n> Table Cell Size ["+tableCellSize+"]"
					+"\n> Row Cell Size ["+rowCellSize+"]");
		} else if (n > 0 && autoColSpan){
			TDCell last = null;
			for (int k = cells.size() - 1; k >= 0; k--){
				if (cells.get(k).isShow()){
					last = cells.get(k);
					break;
				}
			}
			if (null == last){
				return null;
			}
			last.setColSpan(last.getColSpan() + n);
		}
		StringBuilder tStr = new StringBuilder();
		for (TDCell cell : cells){
			if (isShow())
				tStr.append(cell);
		}
		return tStr.toString();
	}
	
	private Table baseTable;
	public Table getBaseTable() {
		if (null == baseTable){
			throw new WrongDocumentObject("No Base Table.");
		}
		return baseTable;
	}
	
	private List<TDCell> cells = new ArrayList<TDCell>();
	public TDCell getCell(int rowIndex){
		if (cells.size() > rowIndex){
			return cells.get(rowIndex);
		}
		return null;
	}
	public List<TDCell> getCells() {
		return cells;
	}
	public List<ExcelStyle> getExcelStyles(){
		List<ExcelStyle> excelStyles = new ArrayList<ExcelStyle>();
		for (TDCell c : cells){
			if (c instanceof ExcelStyle){
				excelStyles.add((ExcelStyle) c);
			}
		}
		return excelStyles;
	}
	public TableRow setCells(List<TDCell> cells) {
		this.cells = cells;
		return this;
	}
	public TDCell addCell(Object o){
		TDCell cell;
		if (o instanceof TDCell)
			cell = (TDCell) o;
		else
			cell = new TDCell(this).setInner(o);
		cells.add(cell);
		return cell;
	}
	public ExcelStyle addExcelStyle(Object o){
		ExcelStyle excelStyle;
		if (o instanceof ExcelStyle)
			excelStyle = (ExcelStyle) o;
		else
			excelStyle = (ExcelStyle) new ExcelStyle(this);
		excelStyle.setInner(o);
		cells.add(excelStyle);
		return excelStyle;
	}
	public TDCell addCell(Object o , int index){
		TDCell cell;
		if (o instanceof TDCell)
			cell = (TDCell) o;
		else
			cell = new TDCell(this).setInner(o);
		try {
			cells.add(index , cell);
		} catch (IndexOutOfBoundsException e) {
			cells.add(cell);
		}
		return cell;
	}
	public ExcelStyle addExcelStyle(Object o , int index){
		ExcelStyle excelStyle;
		if (o instanceof ExcelStyle)
			excelStyle = (ExcelStyle) o;
		else
			excelStyle = (ExcelStyle) new ExcelStyle(this);
		excelStyle.setInner(o);
		try {
			cells.add(index , excelStyle);
		} catch (IndexOutOfBoundsException e) {
			cells.add(excelStyle);
		}
		return excelStyle;
	}
	public TableRow addCells(Object... cells){
		for (Object o : cells){
			addCell(o);
		}
		return this;
	}
	public TableRow addExcelStyles(Object... excelStyles){
		for (Object o : excelStyles){
			addExcelStyle(o);
		}
		return this;
	}
	public int cellSize(){
		int tempNumber = 0;
		for (TDCell cell : cells){
			if (! cell.isShow()){
				continue;
			}
			tempNumber = tempNumber + cell.getColSpan();
		}
		tempNumber += rowSpanCell();
		return tempNumber;
	}
	
	public int rowSpanCell(){
		int tempNumber = 0;
		List<Integer> spans = new ArrayList<Integer>();
		List<Integer> cells = new ArrayList<Integer>();
		List<TableRow> rows = getBaseTable().getRows();
		for (int k = 0; k < rows.size() && ! this.equals(rows.get(k)); k++){
			List<Integer> newSpans = new ArrayList<Integer>();
			List<Integer> newCells = new ArrayList<Integer>();
			for (int n = 0; n < spans.size(); n++){
				spans.set(n, spans.get(n) - 1);
				if (spans.get(n) > 1){
					newSpans.add(spans.get(n));
					newCells.add(cells.get(n));
				}
			}
			spans = newSpans;
			cells = newCells;
			for (TDCell cell : rows.get(k).getCells()){
				if (cell.getRowSpan() > 1){
					spans.add(cell.getRowSpan());
					cells.add(cell.getColSpan());
				}
			}
		}
		for (int k : cells){
			tempNumber = tempNumber + k;
		}
		return tempNumber;
	}
	
	private boolean autoColSpan = true;
	public boolean isAutoColSpan() {
		return autoColSpan;
	}
	public TableRow setAutoColSpan(boolean autoColSpan) {
		this.autoColSpan = autoColSpan;
		return this;
	}
	
}
